package com.fz.us.oa.web.controller.com;

import com.fz.us.admin.base.bean.BaseEnumManager;
import com.fz.us.admin.base.bean.jqgrid.JqGridFilter;
import com.fz.us.admin.base.bean.jqgrid.JqGridPager;
import com.fz.us.admin.base.bean.search.SearchEnum;
import com.fz.us.admin.base.bean.search.order.Order;
import com.fz.us.admin.base.bean.search.page.PageHelp;
import com.fz.us.admin.base.bean.search.result.SearchResultPaging;
import com.fz.us.admin.base.bean.search.rule.Rule;
import com.fz.us.admin.base.bean.search.rule.RuleHelper;
import com.fz.us.admin.base.utils.DataUtil;
import com.fz.us.admin.company.bean.FlowEnum;
import com.fz.us.admin.company.entity.*;
import com.fz.us.admin.company.service.*;
import com.fz.us.admin.dict.entity.DictItem;
import com.fz.us.admin.dict.service.DictItemService;
import com.fz.us.oa.core.entity.com.Notice;
import com.fz.us.oa.core.entity.com.NoticeRead;
import com.fz.us.oa.core.entity.common.FileManage;
import com.fz.us.oa.core.service.com.NoticeReadService;
import com.fz.us.oa.core.service.com.NoticeService;
import com.fz.us.oa.core.service.common.FileManagerService;
import com.fz.us.oa.web.controller.BaseController;
import com.fz.us.oa.web.shiro.bind.annotation.CurrentUser;
import com.fz.us.oa.web.spring.bind.annotation.RequestJsonParam;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.util.*;

/**
 * Created by ZhuChunXiao on 2017/7/21.
 */
@Controller
@RequestMapping(value = "/com/notice")
public class NoticeController extends BaseController {
    private static final long serialVersionUID = -4162038733258501046L;

    @Autowired
    private DictItemService dictItemService;
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private DutyService dutyService;
    @Autowired
    private TaskEntityService taskEntityService;
    @Autowired
    private RemindService remindService;
    @Autowired
    private UserService userService;
    @Autowired
    private FileManagerService fileManagerService;
    @Autowired
    private NoticeReadService noticeReadService;


    /**
     * 新建，编辑页面
     */
    @RequestMapping(value = "input", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String input(@CurrentUser User user, Model model,String keyId,String draft,String index,String todo,String remind,String record) {
        ArrayList<DictItem> dictItems = getDictItems(user,"noticeType");
        if (StringUtils.isNotEmpty(keyId)){
            String fileId ="";
            Notice notice=noticeService.get(keyId);
            if(notice.getFile() != null && notice.getFile().size()>0){
                for(FileManage f:notice.getFile()){
                    fileId+=f.getId()+",";
                }
            }
            model.addAttribute("keyId", keyId);
            model.addAttribute("notice", notice);
            model.addAttribute("fileId", fileId);
        }
        model.addAttribute("dictItems", dictItems);
        model.addAttribute("draft", draft);
        model.addAttribute("index", index);
        model.addAttribute("todo", todo);
        model.addAttribute("remind", remind);
        model.addAttribute("record", record);
        return "/com/notice_input";
    }

    /**
     * 只读页面
     */
    @RequestMapping(value = "read", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String read(@CurrentUser User user, Model model,String keyId,String draft,String index,String todo,String remind,String record) {
        ArrayList<DictItem> dictItems = getDictItems(user,"noticeType");
        if(StringUtils.isNotEmpty(keyId)) {
            String fileId ="";
            Notice notice=noticeService.get(keyId);
            if(notice.getFile() != null && notice.getFile().size()>0){
                for(FileManage f:notice.getFile()){
                    fileId+=f.getId()+",";
                }
            }
            //添加浏览记录
            if (notice.getNumStatus()==1){
                // 先判断是否已经生成了阅读记录
                List<NoticeRead> noticeQueryList = noticeReadService.findUsersByNoticeRead(user.getId(), keyId);
                if (noticeQueryList.size()==0) {
                    // 生成阅读记录
                    NoticeRead noticeRead = new NoticeRead();
                    noticeRead.setNotice(notice);
                    noticeRead.setCreater(user);
                    noticeRead.setCompany(user.getCompany());
                    noticeRead.setName(user.getName());
                    noticeReadService.saveEntity(noticeRead);
                }
            }
            String isEdit =  isEdit(keyId);
            model.addAttribute("fileId", fileId);
            model.addAttribute("notice", notice);
            model.addAttribute("isEdit", isEdit);
        }

        model.addAttribute("keyId", keyId);
        model.addAttribute("dictItems", dictItems);
        model.addAttribute("draft", draft);
        model.addAttribute("index", index);
        model.addAttribute("todo", todo);
        model.addAttribute("remind", remind);
        model.addAttribute("record", record);
        return "/com/notice_read";
    }

    /**
     * 保存Model数据
     */
    private Notice saveModel(User user, String keyId, String dictItemId, String subject,
                             String isTop, String deptId, String noticeType, String deptIds,
                             String userIds, String content,String fileIds) throws ParseException {

        Notice notice = null;
        if (StringUtils.isBlank(keyId)) {
            notice = new Notice();
            notice.setCreater(user);
            notice.setCompany(user.getCompany());
            notice.setName("公告通知");
        } else {
            notice = noticeService.get(keyId);
        }

        if (StringUtils.isNotBlank(dictItemId)) {
            DictItem dictItem = dictItemService.get(dictItemId);
            notice.setDictItem(dictItem);
            notice.setName(dictItem.getName());
        }

        if (StringUtils.isNotBlank(subject)) {
            notice.setSubject(subject);
        }

        if (StringUtils.isNotBlank(isTop)) {
            notice.setIsTop(Integer.valueOf(isTop));
        }

        if (StringUtils.isNotBlank(deptId)) {
            notice.setIssueDepartment(departmentService.get(deptId));
        }

        if (StringUtils.isNotBlank(noticeType)) {
            int nt = Integer.valueOf(noticeType);
            if(nt == 1){
                if(StringUtils.isNotBlank(deptIds)){
                    String[] depts = StringUtils.split(deptIds,",");
                    HashSet<Department> objs = new HashSet<Department>();
                    for (String id : depts) {
                        Department dept = departmentService.get(id);
                        objs.add(dept);
                    }
                    notice.setNoticeDepartments(objs);
                }
            } else if(nt == 2){
                if (StringUtils.isNotBlank(userIds)) {
                    String[] uids = StringUtils.split(userIds,",");
                    HashSet<User> users = new HashSet<User>();
                    for (String uid : uids) {
                        User u = userService.get(uid);
                        users.add(u);
                    }
                    notice.setNoticeUsers(users);
                }
            }
            notice.setNoticeType(nt);
        }


        if (StringUtils.isNotBlank(content)) {
            notice.setContent(content);
        }

        List<FileManage> fileManageList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(fileIds)){
            for(String f:fileIds.split(",")){
                fileManageList.add(fileManagerService.get(f.trim()));
            }
        }
        notice.setFile(fileManageList);

        if (notice.getForm() == null) {
            notice.setForm("公告通知登记表");
        }

        return notice;
    }

    /**
     * 保存操作
     */
    @RequestMapping(value = "save", method = RequestMethod.POST)
    public Object save(@CurrentUser User user,
                       @RequestParam(required = false) String keyId, String dictItemId, String subject,
                       String isTop, String deptId, String noticeType, String deptIds,
                       String userIds, String content,String fileIds) throws ParseException{

        Map<String,Object> rMap=new HashMap<String,Object>();
        Notice notice = saveModel(user, keyId, dictItemId, subject, isTop, deptId, noticeType, deptIds, userIds, content, fileIds);
        if(StringUtils.isNotEmpty(keyId)){
            noticeService.update(notice);
            rMap.put("message", "更新成功");
        } else {
            noticeService.save(notice, "com.fz.us.oa.core.entity.com.Notice");
            rMap.put("message","保存成功");
        }
        rMap.put("state", "1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    // 提交
    @RequestMapping(value = "commit", method = RequestMethod.POST)
    public Object commit(@CurrentUser User user,
                         @RequestParam(required = false) String keyId, String dictItemId, String subject,
                         String isTop, String deptId, String noticeType, String deptIds,
                         String userIds, String content,String fileIds, String curDutyId, String comment) throws ParseException{

        Map<String,Object> rMap=new HashMap<String,Object>();
        Notice notice = saveModel(user, keyId, dictItemId, subject, isTop, deptId, noticeType, deptIds, userIds, content, fileIds);
        notice.setDateApply(new Date());

        if (StringUtils.isNotEmpty(keyId)) {
            noticeService.approve(notice, dutyService.get(curDutyId), comment);
        } else {
            noticeService.commit(notice, "com.fz.us.oa.core.entity.com.Notice", dutyService.get(curDutyId));
        }

        if(notice.getProcessState().name().equals("Finished")){
            doFinished(notice);
        }

        rMap.put("message","提交成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    //审批
    @RequestMapping(value = "approve", method = RequestMethod.POST)
    public Object approve(@CurrentUser User user, String keyId,  String curDutyId, String comment){
        Map<String,Object> rMap=new HashMap<String,Object>();
        Notice notice=noticeService.get(keyId);
        noticeService.approve(notice, dutyService.get(curDutyId), comment);

        //归档后...
        if(notice.getProcessState().name().equals("Finished")){
            doFinished(notice);
        }

        rMap.put("message","提交成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    public void doFinished(Notice notice){
        notice.setNumStatus(1);
        noticeService.update(notice);

        if(notice.getNoticeType()==0){
            Map<String, Object> map=new HashMap<String, Object>();
            map.put("state",BaseEnumManager.StateEnum.Enable);
            List<User> userList=userService.getList(map);
            for(User user1:userList){
                Remind remind = new Remind();
                remind.setUser(user1);
                remind.setBussinessKey("notice");
                remind.setKeyId(notice.getId());
                remind.setContent("您有一条公告通知需要查看");
                remindService.save(remind);
            }
            System.out.println("发送全体，给"+userList.size()+"人发送了通知");
        }else if(notice.getNoticeType()==1){
            Set<User> userSet=new HashSet<User>();
            for(Department dept:notice.getNoticeDepartments()){
                Set<Power> powerSet=dept.getPowerSet();
                for(Power power:powerSet){
                    List<User> usersList=dutyService.getPersons(dept,power.getPost());
                    for(User user1:usersList){
                        userSet.add(user1);
                    }
                }
            }
            for(User user1:userSet){
                Remind remind = new Remind();
                remind.setUser(user1);
                remind.setBussinessKey("notice");
                remind.setKeyId(notice.getId());
                remind.setContent("您有一条公告通知需要查看");
                remindService.save(remind);
            }
            System.out.println("发送部门，给"+userSet.size()+"人发送了通知");
        }else if(notice.getNoticeType()==2){
            for(User user1:notice.getNoticeUsers()){
                Remind remind = new Remind();
                remind.setUser(user1);
                remind.setBussinessKey("notice");
                remind.setKeyId(notice.getId());
                remind.setContent("您有一条公告通知需要查看");
                remindService.save(remind);
            }
            System.out.println("发送个人，给"+notice.getNoticeUsers().size() +"人发送了通知");
        }
    }

    /**
     * 退回
     * @return
     */
    @RequestMapping(value = "back", method = RequestMethod.POST)
    public Object back(@CurrentUser User user, String keyId,String curDutyId, String comment) {
        if (StringUtils.isNotEmpty(keyId)) {
            Notice notice=noticeService.get(keyId);
            noticeService.back(notice, dutyService.get(curDutyId), comment);
        }
        Map<String,Object> rMap=new HashMap<String,Object>();
        rMap.put("message","退回成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }
    /**
     * 否决
     * @return
     */
    @RequestMapping(value = "deny", method = RequestMethod.POST)
    public Object deny(@CurrentUser User user, String keyId,String curDutyId, String comment) {
        if (StringUtils.isNotEmpty(keyId)) {
            Notice notice=noticeService.get(keyId);
            noticeService.deny(notice, dutyService.get(curDutyId), comment);
        }
        Map<String,Object> rMap=new HashMap<String,Object>();
        rMap.put("message","否决成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    /**
     * 列表
     */
    @RequestMapping(value = "list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> list(@CurrentUser User user,
                                    JqGridPager pager,
                                    @RequestJsonParam(value = "filters", required = false) JqGridFilter filters) {
        Company company = user.getCompany();
        // 排序
        Order order = Order.order("isTop", SearchEnum.OrderType.desc);
        SearchResultPaging searchResult = null;
        List<Rule> rules = getSearchFilterRules(pager.getSearch(), filters);

        rules.add(RuleHelper.or(
                RuleHelper.eq("noticeType", 0), // 全体员工
                RuleHelper.and(RuleHelper.eq("noticeType", 1), // 部门
                        RuleHelper.sql("'" + user.getId() + "' in (select user_id from sys_duty where power_id in " +
                                "(select id from sys_power where department_id in (" +
                                "select noticeDepartments_id from ec_notice_sys_department where ec_notice_id = this_.id)) )")),
                RuleHelper.and(RuleHelper.eq("noticeType", 2), // 个人
                        RuleHelper.sql("'" + user.getId() + "' in (select noticeUsers_id from ec_notice_sys_user where ec_notice_id = this_.id )")
                )));


        Map<String,Object> params = new HashMap<String,Object>();
        params.put("company", company);
        params.put("state", BaseEnumManager.StateEnum.Enable);

            //所有单子
            searchResult = noticeService.paging(null,rules,order,
                    "com.fz.us.oa.core.entity.com.Notice",
                    new FlowEnum.ProcessState []{ FlowEnum.ProcessState.Finished}, params);


        List<Notice> noticeList = searchResult.getList();
        ArrayList<Map<String, Object>> dataRows = new ArrayList<Map<String, Object>>();
        Map<String, Object> data = new HashMap<String, Object>();
        Map<String,Object> rMap;

            for(Notice notice: noticeList){
                rMap = new HashMap<String, Object>();
                rMap.put("id", StringUtils.isEmpty(notice.getId())?"":notice.getId());
                rMap.put("name", StringUtils.isEmpty(notice.getName())?"":notice.getName());
                rMap.put("issueDepartment", notice.getIssueDepartment().getName());
                rMap.put("subject", notice.getSubject());
                rMap.put("isTop", notice.getIsTop());
//        rMap.put("creater", entity.getCreater()==null?"": entity.getCreater().getName());
//        rMap.put("processStateName", entity.getProcessState()==null?"": entity.getProcessState().value());
//        rMap.put("createTime", entity.getCreateTime()==null?"": DataUtil.DateTimeToString(entity.getCreateTime()));
                rMap.put("dateApply", notice.getDateApply()==null?"": DataUtil.DateTimeToString(notice.getDateApply()));
                dataRows.add( rMap);
            }

        data.put("dataRows", dataRows);
        data.put("page", searchResult.getPageNumber());
        data.put("rows", searchResult.getPageSize());
        data.put("records", searchResult.getTotalCount());
        data.put("total", searchResult.getPageCount());
        return data;
    }

    /**
     * 取消置顶
     */
    @RequestMapping(value = "cancelTop/{keyId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public Object cancelTop(@CurrentUser User user, @PathVariable String keyId) {
        Notice notice = noticeService.get(keyId);
        notice.setIsTop(0);
        return ajaxJson(noticeService.saveEntity(notice));
    }

    /**
     * 置顶
     */
    @RequestMapping(value = "setTop/{keyId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public Object setTop(@CurrentUser User user, @PathVariable String keyId) {
        Notice notice = noticeService.get(keyId);
        notice.setIsTop(1);
        return ajaxJson(noticeService.saveEntity(notice));
    }

    /**
     * 获取新建人部门
     * @return
     */
    @RequestMapping(value = "getDefaultDept", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public Object getDefaultDept(String curDutyId){
        Map<String, Object> data = new HashMap<String, Object>();
        Duty duty = dutyService.get(curDutyId);
        data.put("department",duty.getPower().getDepartment().getName());
        data.put("departmentId", duty.getPower().getDepartment().getId());
        return  ajaxJson(data);
    }

    /**
     * 浏览记录列表
     */
    @RequestMapping(value = "readList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> readList(@CurrentUser User user,
                                        @RequestParam() String noticeId,
                                        JqGridPager pager,
                                        @RequestJsonParam(value = "filters", required = false) JqGridFilter filters) {
        Company company = user.getCompany();
        // 排序
        Order order = Order.order("createTime", SearchEnum.OrderType.desc);
        SearchResultPaging searchResult = null;

        List<Rule> rules = getSearchFilterRules(pager.getSearch(), filters);
        rules.add(RuleHelper.eq("company", company));   // 所在的公司
        rules.add(RuleHelper.eq("state", BaseEnumManager.StateEnum.Enable));    // 文档为有效的
        rules.add(RuleHelper.eq("notice.id", noticeId));

//        Map<String,Object> params = new HashMap<String,Object>();
//        params.put("company", company);
//        params.put("state", BaseEnumManager.StateEnum.Enable);
//        params.put("notice", noticeService.get(noticeId));

        //所有单子
        searchResult = noticeReadService.findPagingBySearch(null, rules, order);


        List<NoticeRead> noticeReadList = searchResult.getList();
        ArrayList<Map<String, Object>> dataRows = new ArrayList<Map<String, Object>>();
        Map<String, Object> data = new HashMap<String, Object>();
        Map<String,Object> rMap;

        for(NoticeRead noticeRead: noticeReadList){
            rMap = new HashMap<String, Object>();
            rMap.put("id", noticeRead.getId());
            rMap.put("reader", noticeRead.getName());
            rMap.put("createTime", noticeRead.getCreateTime()==null?"": DataUtil.DateTimeToString(noticeRead.getCreateTime()));
            dataRows.add( rMap);
        }

        data.put("dataRows", dataRows);
        data.put("page", searchResult.getPageNumber());
        data.put("rows", searchResult.getPageSize());
        data.put("records", searchResult.getTotalCount());
        data.put("total", searchResult.getPageCount());
        return data;
    }

}
